package com.yang.demo.extensions;

import com.yang.core.api.RestClient;
import com.yang.core.api.RestClientBuilder;
import com.yang.core.plugins.validation.ContentValidationExtension;
import com.yang.core.plugins.validation.ContentValidationExtension.ContentValidationConfig;
import com.yang.core.plugins.validation.ContentValidationExtension.ValidationType;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 内容验证扩展演示
 * 展示如何使用内容验证扩展检查请求和响应内容
 */
@Slf4j
public class ContentValidationDemo {

    public static void main(String[] args) {
        System.out.println("=== 内容验证扩展演示 ===\n");

        try {
            // 1. 基本内容验证演示
            basicContentValidationDemo();

            // 2. 正则表达式验证演示
            regexValidationDemo();

            // 3. 复合验证规则演示
            compositeValidationDemo();

            // 4. 实际API验证演示
            realApiValidationDemo();

        } catch (Exception e) {
            log.error("演示执行失败", e);
        }
    }

    /**
     * 1. 基本内容验证演示
     */
    private static void basicContentValidationDemo() {
        System.out.println("1. 基本内容验证演示");
        System.out.println("=".repeat(50));

        // 创建验证配置
        ContentValidationConfig config = new ContentValidationConfig();
        config.setEnabled(true);
        config.setFailOnViolation(false); // 验证失败时不抛异常，只记录日志
        config.setLogViolations(true);

        // 添加验证规则：检查请求体中是否包含"test"
        config.addContainsRule("", "test", ValidationType.REQUEST_BODY);

        // 添加验证规则：检查响应体中是否包含"slideshow"
        config.addContainsRule("", "slideshow", ValidationType.RESPONSE_BODY);

        // 创建带有内容验证的客户端
        RestClient client = RestClient.builder()
            .baseUrl("https://httpbin.org")
            .addExtension(new ContentValidationExtension(config))
            .build();

        try {
            // 发送包含"test"的请求
            Map<String, Object> testData = Map.of("message", "This is a test message");
            var response = client.post("/post", testData);
            System.out.println("基本验证 - 请求发送成功");

            // 发送不包含"test"的请求
            Map<String, Object> otherData = Map.of("message", "This is another message");
            response = client.post("/post", otherData);
            System.out.println("基本验证 - 请求发送成功（验证失败但未抛异常）");

        } finally {
            client.close();
        }

        System.out.println();
    }

    /**
     * 2. 正则表达式验证演示
     */
    private static void regexValidationDemo() {
        System.out.println("2. 正则表达式验证演示");
        System.out.println("=".repeat(50));

        // 创建验证配置
        ContentValidationConfig config = new ContentValidationConfig();
        config.setEnabled(true);
        config.setFailOnViolation(false);

        // 添加正则验证规则：检查User-Agent是否包含"RestClient"
        config.addRegexRule("User-Agent", "RestClient", ValidationType.REQUEST_HEADER);

        // 添加正则验证规则：检查响应状态码是否为2xx
        config.addRegexRule("", "^2\\d{2}$", ValidationType.RESPONSE_STATUS);

        // 添加正则验证规则：检查JSON响应中是否有特定字段
        config.addRegexRule("", "\"origin\"", ValidationType.RESPONSE_BODY);

        RestClient client = RestClient.builder()
            .baseUrl("https://httpbin.org")
            .defaultHeader("User-Agent", "RestClient/2.0 Demo")
            .addExtension(new ContentValidationExtension(config))
            .build();

        try {
            // 发送请求验证User-Agent
            var response = client.get("/user-agent");
            System.out.println("正则验证 - User-Agent验证通过");

            // 发送请求验证响应体和状态码
            response = client.get("/ip");
            System.out.println("正则验证 - 响体验证通过");

        } finally {
            client.close();
        }

        System.out.println();
    }

    /**
     * 3. 复合验证规则演示
     */
    private static void compositeValidationDemo() {
        System.out.println("3. 复合验证规则演示");
        System.out.println("=".repeat(50));

        // 创建多个验证规则的配置
        ContentValidationConfig config = new ContentValidationConfig();
        config.setEnabled(true);
        config.setFailOnViolation(false);

        // 请求验证规则
        config.addContainsRule("Content-Type", "application/json", ValidationType.REQUEST_HEADER);
        config.addRegexRule("", "^https://.*", ValidationType.REQUEST_URL); // 验证必须是HTTPS

        // 响应验证规则
        config.addRegexRule("", "^2\\d{2}$", ValidationType.RESPONSE_STATUS); // 2xx状态码
        config.addContainsRule("", "Content-Type", ValidationType.RESPONSE_HEADER); // 响应包含Content-Type

        RestClient client = RestClient.builder()
            .baseUrl("https://httpbin.org")
            .defaultHeader("Content-Type", "application/json")
            .addExtension(new ContentValidationExtension(config))
            .build();

        try {
            // 发送复合验证的请求
            Map<String, Object> data = Map.of("test", "data", "number", 123);
            var response = client.post("/post", data);
            System.out.println("复合验证 - 所有验证规则执行完成");

        } finally {
            client.close();
        }

        System.out.println();
    }

    /**
     * 4. 实际API验证演示
     */
    private static void realApiValidationDemo() {
        System.out.println("4. 实际API验证演示");
        System.out.println("=".repeat(50));

        // 模拟实际场景的验证配置
        ContentValidationConfig config = new ContentValidationConfig();
        config.setEnabled(true);
        config.setFailOnViolation(false);

        // API版本验证
        config.addContainsRule("X-API-Version", "v1", ValidationType.REQUEST_HEADER);

        // 认证令牌验证（检查Bearer令牌格式）
        config.addRegexRule("Authorization", "^Bearer\\s+[A-Za-z0-9-._~+/]+=*$", ValidationType.REQUEST_HEADER);

        // 请求格式验证
        config.addContainsRule("Content-Type", "application/json", ValidationType.REQUEST_HEADER);

        // 响应格式验证
        config.addRegexRule("", "^2\\d{2}$", ValidationType.RESPONSE_STATUS);
        config.addContainsRule("", "application/json", ValidationType.RESPONSE_HEADER);

        // 响应内容验证（确保返回JSON格式）
        config.addRegexRule("", "^\\s*\\{", ValidationType.RESPONSE_BODY); // 以{开头（JSON格式）

        RestClient client = RestClient.builder()
            .baseUrl("https://httpbin.org")
            .defaultHeader("X-API-Version", "v1")
            .defaultHeader("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9")
            .defaultHeader("Content-Type", "application/json")
            .addExtension(new ContentValidationExtension(config))
            .build();

        try {
            // 发送符合所有验证规则的请求
            Map<String, Object> request = Map.of(
                "operation", "validate",
                "parameters", Map.of("type", "content_validation")
            );
            var response = client.post("/post", request);
            System.out.println("实际API验证 - 所有验证规则通过");

            // 测试验证失败的情况（移除Bearer令牌）
            RestClient clientWithoutAuth = RestClient.builder()
                .baseUrl("https://httpbin.org")
                .defaultHeader("X-API-Version", "v1")
                .defaultHeader("Content-Type", "application/json")
                .addExtension(new ContentValidationExtension(config))
                .build();

            try {
                response = clientWithoutAuth.post("/post", request);
                System.out.println("实际API验证 - 验证失败但继续执行（未设置Bearer令牌）");
            } catch (Exception e) {
                System.out.println("实际API验证 - 捕获异常: " + e.getMessage());
            } finally {
                clientWithoutAuth.close();
            }

        } finally {
            client.close();
        }

        System.out.println();
    }

    /**
     * 演示严格验证模式
     */
    public static void strictValidationDemo() {
        System.out.println("5. 严格验证模式演示");
        System.out.println("=".repeat(50));

        ContentValidationConfig config = new ContentValidationConfig();
        config.setEnabled(true);
        config.setFailOnViolation(true); // 严格模式：验证失败时抛异常
        config.setLogViolations(true);

        // 添加严格的验证规则
        config.addContainsRule("X-Required-Header", "required-value", ValidationType.REQUEST_HEADER);
        config.addContainsRule("", "must-appear", ValidationType.REQUEST_BODY);

        RestClient client = RestClient.builder()
            .baseUrl("https://httpbin.org")
            .addExtension(new ContentValidationExtension(config))
            .build();

        try {
            // 这个请求会失败，因为缺少必需的头部和内容
            Map<String, Object> data = Map.of("missing", "required-content");
            var response = client.post("/post", data);
            System.out.println("严格验证 - 不应该到达这里");

        } catch (ContentValidationExtension.ContentValidationException e) {
            System.out.println("严格验证 - 正确捕获验证异常: " + e.getMessage());
        } finally {
            client.close();
        }

        System.out.println();
    }

    /**
     * 演示动态添加验证规则
     */
    public static void dynamicValidationDemo() {
        System.out.println("6. 动态验证规则演示");
        System.out.println("=".repeat(50));

        // 创建基础配置
        ContentValidationConfig config = new ContentValidationConfig();
        config.setEnabled(true);
        config.setFailOnViolation(false);

        // 动态添加验证规则
        config.addContainsRule("X-Trace-ID", "trace-", ValidationType.REQUEST_HEADER);
        config.addRegexRule("", "\\d{4}-\\d{2}-\\d{2}", ValidationType.RESPONSE_BODY); // 验证日期格式

        RestClient client = RestClient.builder()
            .baseUrl("https://httpbin.org")
            .defaultHeader("X-Trace-ID", "trace-" + System.currentTimeMillis())
            .addExtension(new ContentValidationExtension(config))
            .build();

        try {
            Map<String, Object> data = Map.of(
                "date", "2025-10-11",
                "message", "Dynamic validation test"
            );
            var response = client.post("/post", data);
            System.out.println("动态验证 - 动态规则验证成功");

        } finally {
            client.close();
        }

        System.out.println();
    }
}